
#include<stdio.h>

#define STATES_COUNT 4
#define EVENT_COUNT 6

#define CPU_READ_D 0
#define CPU_WRITE 1
#define CPU_READ_I 2
#define SNOOP_INVALIDATE 3
#define SNOOP_READ 4
#define SNOOP_WRITE 5
#define SNOOP_RFO 6

#define SN_HIT 0
#define SN_MISS 1



int update_MESI(int CPU_IN, int SN_IN, int SET, int WAY);

typedef enum STATE
	{
		I,
		M, 
		S,
		E
	} STATE;



int update_MESI(int CPU_IN, int SN_IN, int SET, int WAY)
{


	STATE CURRENT_STATE = M; // L2Cache[SET][WAY].MESI_Status
	STATE NEXT_STATE;


	switch (CURRENT_STATE) {
	case I:

		if ((CPU_IN == CPU_READ_D || CPU_IN == CPU_READ_I ) && SN_IN == SN_HIT)
			NEXT_STATE = S;
		
		else if ((CPU_IN == CPU_READ_D || CPU_IN == CPU_READ_I) && SN_IN == SN_MISS)
			NEXT_STATE = E;
		
		else if (CPU_IN == CPU_WRITE)
			NEXT_STATE = M;

		else if (CPU_IN == SNOOP_WRITE)
			NEXT_STATE = I;
				
		else
			NEXT_STATE = I;

		break;

	case M:

		if (CPU_IN == CPU_READ_D || CPU_IN == CPU_READ_I)
			NEXT_STATE = M;
		
		else if (CPU_IN == CPU_WRITE)
			NEXT_STATE = M;

		else if (CPU_IN == SNOOP_RFO)
			NEXT_STATE = I;

		else if (CPU_IN == SNOOP_READ)
			NEXT_STATE = S;

		else if (CPU_IN == SNOOP_WRITE)
			NEXT_STATE = I;
		break;


	case S:

		if (CPU_IN == CPU_READ_D || CPU_IN == CPU_READ_I)
			NEXT_STATE = S;
		
		else if (CPU_IN == CPU_WRITE)
			NEXT_STATE = M;

		else if (CPU_IN == SNOOP_READ)
			NEXT_STATE = S;

		else if (CPU_IN == SNOOP_RFO)
			NEXT_STATE = I;

		else if (CPU_IN == SNOOP_WRITE)
			NEXT_STATE = I;

		break;

	case E:

		if (CPU_IN == CPU_READ_D || CPU_IN == CPU_READ_I)
			NEXT_STATE = E;
		
		else if (CPU_IN == CPU_WRITE)
			NEXT_STATE = M;

		else if (CPU_IN == SNOOP_RFO)
			NEXT_STATE = I;

		else if (CPU_IN == SNOOP_READ)
			NEXT_STATE = S;

		else if (CPU_IN == SNOOP_WRITE)
			NEXT_STATE = I;

		break;
	}
	printf("NEXT STATE = %d", NEXT_STATE);
	return CURRENT_STATE;
}



void main()
{
	int a = 5, b = 1, c = 10, d = 4;
	STATE CURRENT_S;
	CURRENT_S = update_MESI(a,b,c,d);

	printf(" CURRENT STATE : %d",CURRENT_S);
	getch();

	
}

